#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
数据库操作日志模块
用于记录数据库的增删改查操作
"""

import logging
import functools
import traceback
from django.db.models import Model

# 获取数据库操作日志记录器
db_logger = logging.getLogger('db')


def log_db_operation(operation_type):
    """
    数据库操作日志装饰器
    
    Parameters:
        operation_type: 操作类型，如 "CREATE", "UPDATE", "DELETE", "QUERY"
    """
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            # 提取模型名称和对象信息
            model_name = None
            object_id = None
            
            # 尝试从参数中获取模型实例
            for arg in args:
                if isinstance(arg, Model):
                    model_name = arg.__class__.__name__
                    if hasattr(arg, 'pk') and arg.pk:
                        object_id = arg.pk
                    break
            
            # 从kwargs中获取模型实例
            if not model_name and 'instance' in kwargs and isinstance(kwargs['instance'], Model):
                model_name = kwargs['instance'].__class__.__name__
                if hasattr(kwargs['instance'], 'pk') and kwargs['instance'].pk:
                    object_id = kwargs['instance'].pk
            
            # 记录操作前的日志
            log_message = f"Operation: {operation_type}"
            if model_name:
                log_message += f", Model: {model_name}"
            if object_id:
                log_message += f", ID: {object_id}"
            
            try:
                # 记录开始操作的日志
                db_logger.info(log_message)
                
                # 执行原函数
                result = func(*args, **kwargs)
                
                # 对于创建操作，记录创建后的对象ID
                if operation_type == "CREATE" and result and hasattr(result, 'pk'):
                    db_logger.info(f"Created {model_name} with ID: {result.pk}")
                
                # 记录操作成功的日志
                db_logger.info(f"{operation_type} operation successful")
                return result
                
            except Exception as e:
                # 记录操作失败的日志
                error_message = f"{operation_type} operation failed: {str(e)}"
                db_logger.error(error_message)
                db_logger.error(traceback.format_exc())
                raise
                
        return wrapper
    return decorator


# 预定义的装饰器
create_log = log_db_operation("CREATE")
update_log = log_db_operation("UPDATE")
delete_log = log_db_operation("DELETE")
query_log = log_db_operation("QUERY")


def log_model_save(cls):
    """
    装饰模型类，自动为save和delete方法添加日志
    
    使用方法:
    @log_model_save
    class MyModel(models.Model):
        ...
    """
    original_save = cls.save
    original_delete = cls.delete
    
    @functools.wraps(original_save)
    def logged_save(self, *args, **kwargs):
        is_new = self.pk is None
        operation_type = "CREATE" if is_new else "UPDATE"
        
        model_name = self.__class__.__name__
        
        log_message = f"Operation: {operation_type}, Model: {model_name}"
        if not is_new and self.pk:
            log_message += f", ID: {self.pk}"
            
        try:
            db_logger.info(log_message)
                
            result = original_save(self, *args, **kwargs)
            
            if is_new and self.pk:
                db_logger.info(f"Created {model_name} with ID: {self.pk}")
                
            db_logger.info(f"{operation_type} operation successful")
            return result
            
        except Exception as e:
            error_message = f"{operation_type} operation failed: {str(e)}"
            db_logger.error(error_message)
            db_logger.error(traceback.format_exc())
            raise
    
    @functools.wraps(original_delete)
    def logged_delete(self, *args, **kwargs):
        model_name = self.__class__.__name__
        object_id = self.pk
        
        log_message = f"Operation: DELETE, Model: {model_name}"
        if object_id:
            log_message += f", ID: {object_id}"
            
        try:
            db_logger.info(log_message)
            result = original_delete(self, *args, **kwargs)
            db_logger.info(f"DELETE operation successful")
            return result
            
        except Exception as e:
            error_message = f"DELETE operation failed: {str(e)}"
            db_logger.error(error_message)
            db_logger.error(traceback.format_exc())
            raise
    
    cls.save = logged_save
    cls.delete = logged_delete
    return cls 